
#include "hardware.h"
#include "n32g030_flash.h"


void	LED_PowerOn(U8 leds)
{
	switch (leds)
	{
		case LED_START_WORKING:
			LED6_PowerOn;
			break;
		case LED_POWER_ON_STS:
			LED5_PowerOn;
			break;
		case LED_ALL:
			LED5_PowerOn;	
			LED6_PowerOn;
			break;
		default:
			break;
	}
}

void	LED_PowerOff(U8 leds)
{
	switch (leds)
	{
		case LED_START_WORKING:
			LED6_PowerOff;
			break;
		case LED_POWER_ON_STS:
			LED5_PowerOff;
			break;
		case LED_ALL:
			LED5_PowerOff;	
			LED6_PowerOff;
			break;
		default:
			break;
	}
}

void	FanPowerOn(void)
{
	GPIO_SetBits(FAN_CTL_PORT, FAN_CTL_PIN) ;
	machine.FanPower = true;
}

void FanPowerOff(void)
{	
	GPIO_ResetBits(FAN_CTL_PORT, FAN_CTL_PIN)	;
	machine.FanPower = false;
}

void	WuHuaPowerOn(void)
{
	GPIO_SetBits(WUFHUA_CTL_PORT,	WUFHUA_CTL_PIN) ;
	machine.WuHuaPower = true;
}

void WuHuaPowerOff(void)
{
	GPIO_ResetBits(WUFHUA_CTL_PORT,	WUFHUA_CTL_PIN)	;
	machine.WuHuaPower = false;
}

void	ChouYePowerOn(void)
{
	machine.ChuChouYeWeight = Get_Weight();
	if (machine.ChuChouYeWeight > 100)
	{
		machine.ChuChouYeNeed = AddWaterWeight * CurSetting.SetItem.percent / 100;
		GPIO_SetBits(CHOUYE_CTL_PORT,	CHOUYE_CTL_PIN) ;
		machine.ChuChouYePower = true;		
		Error_Flg.BIT.ChuChouYe_Err = NO;	
	}
	else
	{
		Error_Flg.BIT.ChuChouYe_Err = YES;
	}
}

void ChouYePowerOff(void)
{
	GPIO_ResetBits(CHOUYE_CTL_PORT,	CHOUYE_CTL_PIN) ;
	machine.ChuChouYePower = false;
};
					
void	Buzzer(u8 count)
{
	for(; count > 0; count --)
	{
		BuzzerPowerOn;
		delay_ms (10);
		BuzzerPowerOff;
		delay_ms (50);
	}
}

U8	ReadKey(void)
{
	U8	key = NO_KEY_PRESSED,temp;
	
	temp = (u8)GPIO_ReadInputData(KEY_INPUT_PORT);// >> 4 & 0xf;
	delay_us(100);
	if (temp == (u8)GPIO_ReadInputData(KEY_INPUT_PORT))
	{
		key = (temp >> 4) & 0x0f;
		if (temp & 0x02)
			key |= KEY_ZERO_PRESSED;
		key = ~key & KEY_MASK;
	}
	return key;	
}

void	WaitReleaseKey(void)
{
	while(true)
	{
		if (ReadKey() == NO_KEY_PRESSED)
			break;
	}
}

void TZPowerOn(void)
{
	GPIO_SetBits(TZ_PORT,TZ_PWR_PIN);
	machine.TZSensorPower = true;
}

void TZPowerOff(void)
{
	GPIO_ResetBits(TZ_PORT,TZ_PWR_PIN);
	machine.TZSensorPower = false;
}

void	ShuiFaPowerOn (void)
{
	GPIO_SetBits(SHUI_CTL_PORT,	SHUI_CTL_PIN) ;
	machine.ShuiFaPower = true;
}

void ShuiFaPowerOff(void)
{
	GPIO_ResetBits(SHUI_CTL_PORT,	SHUI_CTL_PIN) ;
	if (machine.TZSensorPowerOff)
	{
		TZPowerOff();
		machine.TZSensorPowerOff = false;
	}
	machine.ShuiFaPower = false;
}
						
void		ProcessMachineStatus(void)
{
	U32 ChuChouYeWeight;
	U8 water_sts;
	
	if (machine.DeviceWorking && machine.ShuiFaPower)
	{
		water_sts = Check_Water_Sensor();
		if(water_sts >= WATER_HIGH_LEVEL)
		{
			if (machine.ShuiFaPower)
			{
				ShuiFaPowerOff();
				TZPowerOff();
				ChouYePowerOn();
			}
		}
	}
	if (machine.ChuChouYePower)
	{
		ChuChouYeWeight = machine.ChuChouYeWeight - Get_Weight();
		if (ChuChouYeWeight > machine.ChuChouYeNeed)
		{
			ChouYePowerOff();
		}
	}
}

void  WuHuaDeviceStartWorking(void)
{
	U8 water_sts;
	
	water_sts = Check_Water_Sensor();
	if (water_sts == WATER_LOW_LEVEL)
	{
		ShuiFaPowerOn();
	}
	else if ((water_sts == WATER_NORMAL_LEVEL) ||(water_sts == WATER_HIGH_LEVEL))
	{
		if ((!machine.ShuiFaPower) && (!machine.ChuChouYePower))
		{
			WuHuaPowerOn();
			FanPowerOn();
		}
	}
}

void	ProcessDeviceWorking(void)
{
	if (machine.DeviceWorking)
	{
		if (WuHuaCtrl.WuHuaStatusChangeTime > 0)
			WuHuaCtrl.WuHuaStatusChangeTime --;
		if (WuHuaCtrl.WuHuaStatusChangeTime == 0)
		{
			InitialWorkingTime();		//WuHua device status is already changed.
			if (WuHuaCtrl.WuHuaStatus == WUHUA_PowerOff)
			{
				WuHuaPowerOff();
				FanPowerOff();
			}
			else{
				WuHuaDeviceStartWorking();
			}
		}
	}
	return;
}

void StopDevice(void)
{
	TZPowerOff();
	ShuiFaPowerOff();
	ChouYePowerOff();
	FanPowerOff();
	WuHuaPowerOff(); 	
	LED_PowerOff(LED_START_WORKING);
}

void	StartDevice(void)
{
	if (machine.DeviceWorking)
	{
		machine.DeviceWorking = false;
		StopDevice();
	}
	else{
		LED_PowerOn(LED_START_WORKING);
		machine.DeviceWorking = true;
		InitialWorkingTime();
		WuHuaDeviceStartWorking();
	}
}

void	Check_Machine_Status(void)
{
#if 1
	if (machine.TZSensorPower)
	{
		if (machine.TZPowerOnTime > 0)
		{
			machine.TZPowerOnTime --;
			if (machine.TZPowerOnTime == 0)
			{
				if (machine.ShuiFaPower == false)
					TZPowerOff();
				else
					machine.TZSensorPowerOff = true;
			}
		}
	}
#endif	
	Check_Sensor();
}


void	Board_Initial(void)
{
    /*SystemInit() function has been called by startup file startup_n32g030.s*/
	GPIO_InitType GPIO_InitStructure;

    /* Initialize Led1~Led3 as output pushpull mode*/
	RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_AFIO, ENABLE);
	RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB | RCC_APB2_PERIPH_AFIO, ENABLE);
	RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC | RCC_APB2_PERIPH_AFIO, ENABLE);
	RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOF | RCC_APB2_PERIPH_AFIO, ENABLE);
//  RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_TIM8, ENABLE);

	GPIO_InitStruct(&GPIO_InitStructure);

	GPIO_InitStructure.Pin = LED5_Power_PIN ;//| LED_Status_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitPeripheral(LED5_PORT, &GPIO_InitStructure);
	LED5_PowerOff;
	GPIO_InitStructure.Pin = LED6_Power_PIN ;//| LED_Status_PIN;
//	GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitPeripheral(LED6_PORT, &GPIO_InitStructure);
	LED6_PowerOff;
	
	GPIO_InitStructure.Pin = LED6_Power_PIN ;//| LED_Status_PIN;
//	GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitPeripheral(LED6_PORT, &GPIO_InitStructure);

	GPIO_InitStructure.Pin = FAN_CTL_PIN | SHUI_CTL_PIN |WUFHUA_CTL_PIN;
//	GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitPeripheral(FAN_CTL_PORT, &GPIO_InitStructure);
	FanPowerOff();
	ShuiFaPowerOff();	
	WuHuaPowerOff();
	
	GPIO_InitStructure.Pin = CHOUYE_CTL_PIN;
	GPIO_InitPeripheral(CHOUYE_CTL_PORT, &GPIO_InitStructure);	
	ChouYePowerOff();

	GPIO_InitStructure.Pin = TZ_PWR_PIN;
	GPIO_InitPeripheral(TZ_PORT, &GPIO_InitStructure);	
	TZPowerOff();

	GPIO_InitStructure.Pin = BuzzerPin;
	GPIO_InitPeripheral(BuzzerPort, &GPIO_InitStructure);	
	
	HX711_Initial(KEY_INPUT_PORT,KEY_ZERO_PIN,CALIBRATE_WEIGHT);
	
	RAM_Initial();
  KeyInputExtiInit(KEY_INPUT_PORT, KEY_ZERO_PIN | KEY1_PIN | KEY2_PIN |KEY3_PIN |KEY4_PIN); 
	InitialMonitor();
	InitialSensor();
}

U32	CalcCheckSum(U8 * pbdata, U8 len)
{
	U32 ChkSum = 0;
	U8 idx;
	
	for (idx = 0;idx < len; idx ++)
		ChkSum += pbdata[idx];
	return ChkSum;	
}

void	SaveSetting(U8 * pbAddr,U8 len)
{
	uint32_t Counter_Num = 0;
	uint32_t Erase_Data;
	U32 * pbSetting;

	pbSetting = (U32 *)pbAddr;
	
	pbSetting [ len / sizeof(U32) - 1] = CalcCheckSum(pbAddr,len - sizeof(u32));

	/* Unlocks the FLASH Program Erase Controller */
	FLASH_Unlock();
    /* Erase */
    if (FLASH_COMPL != FLASH_EraseOnePage(SettingAddr))
    {
        while(1)
        {
            printf("Flash EraseOnePage Error. Please Deal With This Error Promptly\r\n");
        }
    }
		len /= sizeof(U32);
    /* Program */
    for (Counter_Num = 0; Counter_Num < len; Counter_Num ++)
    {
				Erase_Data = pbSetting[Counter_Num];
        if (FLASH_COMPL != FLASH_ProgramWord(SettingAddr + Counter_Num * sizeof(u32), Erase_Data))
        {
            while(1)
            {
                printf("Flash ProgramWord Error. Please Deal With This Error Promptly\r\n");
            }
        }
    }

    /* Locks the FLASH Program Erase Controller */
    FLASH_Lock();
}

void	MemoryCopy (U8 * pbSource, U8 * pbEnd,U8 len)
{
	U8 idx;
	
	for (idx = 0;idx < len; idx ++)
		pbEnd[idx] = pbSource[idx];
}

bool	CheckSetting(void)
{
	bool result = false;
	U32 ChkSum,CheckSum;
	U8 * Addr = (U8 *)SettingAddr;
	
	ChkSum = CalcCheckSum(Addr,sizeof(SETTING_STRUCT) - sizeof(u32));
	CheckSum = ((U32 *)SettingAddr)[sizeof(SETTING_STRUCT) / sizeof(u32) - 1];
	if (ChkSum == CheckSum)
	{
		MemoryCopy(Addr,(U8 *)&CurSetting,sizeof(SETTING_STRUCT));
		result = true;
	}
	return result;
}

void InitialSetting(void)
{
//	U8 idx = 0;
	if (CheckSetting() == false)
	{
		MemoryCopy((U8 *)initSetting,(U8 *)CurSetting.data,sizeof(U32)*Setting_Len);
		SaveSetting((U8 *)&CurSetting,sizeof(SETTING_STRUCT));
	}
	SettingPhase = 0;
}

void KeyInputExtiInit(GPIO_Module* GPIOx, uint16_t Pin)
{
    GPIO_InitType GPIO_InitStructure;
    /*Configure the GPIO pin as input floating*/
    if (Pin <= GPIO_PIN_ALL)
    {
        GPIO_InitStruct(&GPIO_InitStructure);
        GPIO_InitStructure.Pin        = Pin;
        GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_INPUT;// | GPIO_MODE_IT_FALLING;
        GPIO_InitStructure.GPIO_Pull  = GPIO_PULL_UP;
        GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure);
    }
#if 0
    /*Configure key EXTI Line to key input Pin*/
    GPIO_ConfigEXTILine(KEY_INPUT_PORT_SOURCE, KEY_INPUT_PIN_SOURCE);

    /*Set key input interrupt priority*/
    NVIC_InitStructure.NVIC_IRQChannel                   = KEY_INPUT_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority           = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
#endif		
}
